package com.zzl.study.nacos.discovery;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.zzl.study.nacos.NacosServiceInstance;
import com.zzl.study.nacos.NacosServiceMultiManager;
import com.zzl.study.nacos.properties.NacosMultiDiscoveryProperties;
import org.springframework.cloud.client.ServiceInstance;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Nacos多注册中心服务发现对象
 *
 * @author: zhangzl
 * @date: 2025/7/15 10:42
 * @version: 1.0
 */
public class NacosServiceMultiDiscovery {

    /**
     * Nacos多注册中心服务发现属性对象
     */
    private final NacosMultiDiscoveryProperties nacosMultiDiscoveryProperties;

    /**
     * Nacos多注册中心服务管理对象
     */
    private final NacosServiceMultiManager nacosServiceMultiManager;

    /**
     * 构造函数
     *
     * @param nacosMultiDiscoveryProperties Nacos多注册中心服务发现属性对象
     * @param nacosServiceMultiManager      Nacos多注册中心服务管理对象
     */
    public NacosServiceMultiDiscovery(NacosMultiDiscoveryProperties nacosMultiDiscoveryProperties, NacosServiceMultiManager nacosServiceMultiManager) {
        this.nacosMultiDiscoveryProperties = nacosMultiDiscoveryProperties;
        this.nacosServiceMultiManager = nacosServiceMultiManager;
    }

    /**
     * 获取服务实例列表
     *
     * @param serviceId 服务ID
     * @return 服务实例列表
     * @throws NacosException Nacos异常
     */
    public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
        String group = this.nacosMultiDiscoveryProperties.getGroup();
        List<NamingService> namingServiceList = namingServices();
        List<Instance> allInstances = new ArrayList<>();
        for (NamingService namingService : namingServiceList) {
            List<Instance> instances = namingService.selectInstances(serviceId, group, true);
            allInstances.addAll(instances);
        }
        return hostToServiceInstanceList(allInstances, serviceId);
    }

    /**
     * 获取服务列表
     *
     * @return 服务列表
     * @throws NacosException Nacos异常
     */
    public List<String> getServices() throws NacosException {
        String group = this.nacosMultiDiscoveryProperties.getGroup();
        List<NamingService> namingServiceList = namingServices();
        List<String> allServices = new ArrayList<>();
        for (NamingService namingService : namingServiceList) {
            ListView<String> services = namingService.getServicesOfServer(1, Integer.MAX_VALUE, group);
            allServices.addAll(services.getData());
        }
        return allServices;
    }

    /**
     * Nacos服务实例列表转换成Spring Cloud服务实例列表
     *
     * @param instances nacos服务实例列表
     * @param serviceId 服务ID
     * @return Spring Cloud服务实例列表
     */
    public static List<ServiceInstance> hostToServiceInstanceList(List<Instance> instances, String serviceId) {
        List<ServiceInstance> result = new ArrayList<>(instances.size());
        for (Instance instance : instances) {
            ServiceInstance serviceInstance = hostToServiceInstance(instance, serviceId);
            if (serviceInstance != null) {
                result.add(serviceInstance);
            }
        }
        return result;
    }

    /**
     * Nacos服务实例转换成Spring Cloud服务实例
     *
     * @param instance  nacos服务实例
     * @param serviceId 服务ID
     * @return Spring Cloud服务实例
     */
    public static ServiceInstance hostToServiceInstance(Instance instance, String serviceId) {
        if (instance == null || !instance.isEnabled() || !instance.isHealthy()) {
            return null;
        }
        NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
        nacosServiceInstance.setHost(instance.getIp());
        nacosServiceInstance.setPort(instance.getPort());
        nacosServiceInstance.setServiceId(serviceId);
        nacosServiceInstance.setInstanceId(instance.getInstanceId());
        Map<String, String> metadata = new HashMap<>();
        metadata.put("nacos.instanceId", instance.getInstanceId());
        metadata.put("nacos.weight", instance.getWeight() + "");
        metadata.put("nacos.healthy", instance.isHealthy() + "");
        metadata.put("nacos.cluster", instance.getClusterName());
        if (instance.getMetadata() != null) {
            metadata.putAll(instance.getMetadata());
        }
        metadata.put("nacos.ephemeral", String.valueOf(instance.isEphemeral()));
        nacosServiceInstance.setMetadata(metadata);
        if (metadata.containsKey("secure")) {
            boolean secure = Boolean.parseBoolean(metadata.get("secure"));
            nacosServiceInstance.setSecure(secure);
        }
        return nacosServiceInstance;
    }

    /**
     * 获取Nacos服务实例集合
     *
     * @return Nacos服务实例集合
     */
    private List<NamingService> namingServices() {
        return this.nacosServiceMultiManager.getNamingServices();
    }

}
